Goal: an location based app!
https://github.com/mikelmaron/Cartonama
http://aeneous.coolwrks.com/sajjad/Cartonama-Workshop-Hasgeek.iso
http://workshop.cartonama.org/
http://groups.google.com/group/cartonama-workshop
Came away with a solid base understanding of what OpenStreetMap is all about ... the motivations and the approach.
http://www.youtube.com/watch?v=fpHKb-SZRh8
source http://news.bbc.co.uk/2/hi/uk_news/magazine/8517057.stm
sourc http://gallery.me.com/dbullington#100816&view=null&bgcolor=black&sel=12
http://voiceofkibera.org/
http://blog.foursquare.com/2012/02/29/foursquare-is-joining-the-openstreetmap-movement-say-hi-to-pretty-new-maps/
Understand how to use a GPS and collect data for OSM
Using the GPS
Record Data
Use of GPSBabel to download GPS data
Connect GPS with USB cable
!sh sudo gpsbabel -i Garmin -f usb: -o gpx -F waypoints.gpx
Facility with JOSM and Potlatch editors.
Understand Tagging, Map Features, Editing Presets in JOSM and Potlatch
http://wiki.openstreetmap.org/wiki/Map_Features
highway = bus_stop
name = Domlur
name:en = Domlur
name:kn = ಡೊಮಲೂರು
http://www.openstreetmap.org/browse/changeset/10839653
http://wiki.openstreetmap.org/wiki/APIs
GET http://api.openstreetmap.org/api/0.6/way/35
1 <osm version="0.6" generator="OpenStreetMap server">
2 <way id="35" visible="true" timestamp="2010-12-06T14:41:05Z"
3 version="5" changeset="6564105" user="blackadder" uid="735">
4 <nd ref="200542"/>
5 <nd ref="274057218"/>
6 <nd ref="1024965354"/>
7 <nd ref="200550"/>
8 <nd ref="1024940305"/>
9 <nd ref="1024940306"/>
10 <nd ref="1024940307"/>
11 <nd ref="200551"/>
12 <nd ref="200553"/>
13 <tag k="highway" v="footway"/>
14 <tag k="is_in" v="Sutton Coldfield"/>
15 <tag k="note" v="Fire Access Route"/>
16 <tag k="surface" v="paved"/>
17 </way>
18 </osm>
1 <presets>
2 <group name="Health Service">
3
4 <item name="Basics">
5 <label text="Health Service" />
6
7 <text key="name" text="Service Name" />
8 <combo key="opening_hours" text="Opening Hours" values="24/7,Mo-Fr 08:30-20:00,Tu-Su 08:00-15:00; Sa 08:00-12:00"
9 default="" delete_if_empty="true" link="http://wiki.openstreetmap.org/wiki/Key:opening_hours" />
10
11 <label text=" " />
12 <text key="contact:phone" text="Mobile"
13 link="http://wiki.openstreetmap.org/wiki/Key:contact" />
14 <text key="contact:email" text="Email"
15 link="http:///wiki.openstreetmap.org/wiki/Key:contact" />
16 </group>
17 </presets>
http://josm.openstreetmap.de/wiki/TaggingPresets
http://wiki.openstreetmap.org/wiki/Develop
OSM bus stop data for Bangalore
http://open.mapquestapi.com/xapi/api/0.6/node[highway=bus_stop][bbox=77.4256,12.8254,77.7844,13.1396]
https://github.com/mikelmaron/Cartonama/blob/master/data/busstops-bangalore.xml
"Raster is faster but vector is correcter."
32.0
0.0
0.0
-32.0
691200.0
4576000.0
(example borrowed from Wikipedia)
POINT(77.58 12.96)LINESTRING(77.56 12.95, 77.57 12.95, 77.58 12.96)POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))POLYGON((0 0, 0 4, 4 4, 4 0, 0 0), (3 3, 3 1, 1 1, 1 3, 3 3))http://geojson.org/
{ "type": "Point", "coordinates": [77.58, 12.96] }
{
"type": "LineString",
"coordinates": [ [100.0, 0.0], [101.0, 1.0] ]
}
{
"type": "Polygon",
"coordinates": [
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]
]
}
{
"type": "Polygon",
"coordinates": [
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],
[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]
]
}
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [77.58, 12.96]},
"properties": {"name": "Bangalore"}
}
N.B. Properties can be any legit JSON object!
{
"type": "FeatureCollection",
"features": [ ... ]
}
$ createdb template_gis
$ createlang plpgsql template_gis
$ psql template_gis </usr/share/postgis/postgis.sql
$ psql template_gis </usr/share/postgis/spatial_ref_sys.sql
$ createdb -Ttemplate_gis my_new_postgis_db
Column | Type | Modifiers
-------------------+------------------------+-----------
f_table_catalog | character varying(256) | not null
f_table_schema | character varying(256) | not null
f_table_name | character varying(256) | not null
f_geometry_column | character varying(256) | not null
coord_dimension | integer | not null
srid | integer | not null
type | character varying(30) | not null
Column | Type | Modifiers
-----------+-------------------------+-----------
srid | integer | not null
auth_name | character varying(256) |
auth_srid | integer |
srtext | character varying(2048) |
proj4text | character varying(2048) |
CREATE TABLE poi (id SERIAL, name VARCHAR);
SELECT AddGeometryColumn('poi','location',4326,'POINT',2);
# \d poi
Table "public.poi"
Column | Type | Modifiers
----------+-------------------+--------------------------------------
id | integer | not null default nextval(...)
name | character varying |
location | geometry |
Check constraints:
"enforce_dims_location" CHECK (st_ndims(location) = 2)
"enforce_geotype_location" CHECK
(geometrytype(location) = 'POINT'::text OR location IS NULL)
"enforce_srid_location" CHECK (st_srid(location) = 4326)
# INSERT INTO poi (name, location)
VALUES ('CIS', 'POINT(77.6375384 12.9647134)');
ERROR: new row for relation "poi" violates check constraint
"enforce_srid_location"
# INSERT INTO poi (name, location)
VALUES ('CIS', 'SRID=4326;POINT(77.6375384 12.9647134)');
INSERT 0 1
# SELECT * FROM poi;
id | name | location
----+------+----------------------------------------------------
2 | CIS | 0101000020E61000006D7CDC6DCD685340A4062EEAEEED2940
(1 row)
# SELECT id, name, AsText(location) FROM poi;
id | name | astext
----+------+------------------------------
2 | CIS | POINT(77.6375384 12.9647134)
(1 row)
"Dimensionally Extended 9 Intersection Model" (DE-9IM)
$ shp2pgsql -s4326 -I world_borders.shp admin0 | psql my_db
Table "public.world_borders"
Column | Type | Modifiers
------------+-----------------------+------------------------------
gid | integer | not null default nextval(...)
cat | double precision |
fips_cntry | character varying(80) |
cntry_name | character varying(80) |
area | double precision |
pop_cntry | double precision |
the_geom | geometry |
Indexes:
"world_borders_pkey" PRIMARY KEY, btree (gid)
"world_borders_the_geom_gist" gist (the_geom)
Check constraints:
"enforce_dims_the_geom" CHECK (st_ndims(the_geom) = 2)
"enforce_geotype_the_geom" CHECK
(geometrytype(the_geom) = 'MULTIPOLYGON'::text ...)
"enforce_srid_the_geom" CHECK (st_srid(the_geom) = 4326)
# SELECT name, cntry_name FROM world_borders, poi
WHERE st_contains(world_borders.the_geom, poi.location);
name | cntry_name
------+------------
CIS | India
(1 row)
SELECT SUM(ST_Area(ST_Transform(the_geom, 32643))) / 1000000
FROM world_borders WHERE cntry_name = 'India';
?column?
------------------
3196343.52393187
(1 row)
SELECT ST_Distance_Sphere(
'POINT(77.6375384 12.9647134)', 'POINT(122.7 37.4)') / 1000;
?column?
------------------
5216.69910277434
(1 row)
# EXPLAIN SELECT name, cntry_name FROM world_borders, poi
WHERE st_contains(world_borders.the_geom, poi.location);
QUERY PLAN
----------------------------------------------------------------------
Nested Loop (cost=0.00..1347.15 rows=1 width=14)
Join Filter: ((world_borders.the_geom && poi.location) AND
_st_contains(world_borders.the_geom, poi.location))
-> Seq Scan on poi (cost=0.00..1.01 rows=1 width=104)
-> Seq Scan on world_borders
(cost=0.00..352.84 rows=3784 width=6982)
(4 rows)
# CREATE INDEX world_borders_the_geom_gist
ON world_borders USING GIST (the_geom);
# EXPLAIN SELECT name, cntry_name FROM world_borders, poi
WHERE st_contains(world_borders.the_geom, poi.location);
QUERY PLAN
----------------------------------------------------------------------
Nested Loop (cost=0.00..1815.00 rows=5 width=42)
Join Filter: _st_contains(world_borders.the_geom, poi.location)
-> Seq Scan on poi (cost=0.00..18.30 rows=830 width=64)
-> Index Scan using world_borders_the_geom_gist on world_borders
(cost=0.00..1.90 rows=1 width=6982)
Index Cond: (the_geom && poi.location)
(6 rows)
$ pgsql2shp my_db poi
Initializing... Done (postgis major version: 1).
Output shape: Point
Dumping: XX [1 rows].
A F/OSS library that speaks dozens and dozens of formats
$ gdalinfo SRTM_fB03_n012e077.tif
Driver: GTiff/GeoTIFF
Files: SRTM_fB03_n012e077.tif
Size is 1201, 1201
Coordinate System is:
GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563,
AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich",0],
UNIT["degree",0.0174532925199433],
AUTHORITY["EPSG","4326"]]
Origin = (76.999583333333334,13.000416666666666)
Pixel Size = (0.000833333333333,-0.000833333333333)
Corner Coordinates:
Upper Left ( 76.9995833, 13.0004167) ( 76d59'58.50"E, 13d 0' 1.50"N)
Lower Left ( 76.9995833, 11.9995833) ( 76d59'58.50"E, 11d59'58.50"N)
Upper Right ( 78.0004167, 13.0004167) ( 78d 0' 1.50"E, 13d 0' 1.50"N)
Lower Right ( 78.0004167, 11.9995833) ( 78d 0' 1.50"E, 11d59'58.50"N)
Center ( 77.5000000, 12.5000000) ( 77d30' 0.00"E, 12d30' 0.00"N)
Band 1 Block=1201x1 Type=Float32, ColorInterp=Gray
$ gdal_translate -of GTiff some_other_format.jpg a_better_format.tif
$ gdal_translate --formats
$ gdalwarp -t_srs EPSG:3875 some_file_in_4326.tif web_mercator.tif
$ gdaladdo satellite_image.tif 2 4 8 16 32
$ ogrinfo world_borders.shp
INFO: Open of `world_borders.shp'
using driver `ESRI Shapefile' successful.
1: world_borders (Polygon)
$ ogrinfo world_borders.shp
Layer name: world_borders
Geometry: Polygon
Feature Count: 3784
Extent: (-180.000000, -90.000000) - (180.000000, 83.623596)
Layer SRS WKT:
(unknown)
CAT: Real (16.0)
FIPS_CNTRY: String (80.0)
CNTRY_NAME: String (80.0)
AREA: Real (15.2)
POP_CNTRY: Real (15.2)
OGRFeature(world_borders):0
CAT (Real) = 1
FIPS_CNTRY (String) = AA
CNTRY_NAME (String) = Aruba
AREA (Real) = 193.00
POP_CNTRY (Real) = 71218.00
POLYGON ((-69.882233 12.41111,-69.946945 12.436666, ...))
$ ogr2ogr -a_srs epsg:4326 world_borders_4326.shp world_borders.shp
$ ogr2ogr -a_srs epsg:4326 -t_srs epsg:3875 world_borders_3875.shp world_borders.shp
$ ogr2ogr -f KML world_borders.kml world_borders.shp
$ ogr2ogr -f PostgreSQL PG:dbname=my_db world_borders.kml
API
$ curl http://api.openstreetmap.org/api/0.6/map?bbox=-0.5,51.25,0.5,51.75
(only returns 50,000 objects)
XAPI
Formats
Planet.osm
$ osm2pgsql -l -d my_db -s -G planet.osm.bz2
$ osm2pgsql -m -d my_db -s -G planet.osm.bz2
$ osm2pgsql -l -d my_db -b -0.5,51.25,0.5,51.75 planet.extract.osm.bz2
Default lives in /usr/share/osm2pgsql/default.style or similar
# OsmType Tag DataType Flags
node,way note text delete
node,way source text delete
node,way created_by text delete
node,way access text linear
node,way admin_level text linear
node,way aerialway text linear
node,way aeroway text polygon
...
http://wiki.openstreetmap.org/wiki/Osmosis
osmosis --read-xml file="planet.osm" --write-apidb database="x"
osmosis --read-xml-change file="planetdiff-1-2.osc"
--read-xml file="planet1.osm"
--apply-change --write-xml file="planet2.osm"
osmosis --read-xml city.osm
--way-key-value keyValueList="railway.tram,railway.tram_stop"
--used-node --write-xml city_tram.osm
bzcat downloaded.osm.bz2 | osmosis\
--read-xml enableDateParsing=no file=-\
--bounding-box top=49.5138 left=10.9351 bottom=49.3866 right=11.201
--write-xml file=-\
| bzip2 > extracted.osm.bz2
http://wiki.openstreetmap.org/wiki/Osmium
/*
run with: osmjs -l sparsetable -j extract-nodes.js OSMFILE
*/
wanted_keys = [ ... ];
Osmium.Callbacks.node = function() {
if(!this.tags["name"] && !this.tags["place_name"]) return;
found_wanted_keys = false;
for (var i = 0; i < wanted_keys.length; i++) {
if (this.tags[wanted_keys[i]]) {
found_wanted_keys = true;
break;
}
}
if (!found_wanted_keys) return;
print(JSON.stringify({
"geom": [this.geom.lon, this.geom.lat],
"tags": this.tags,
"type":"node",
"id": this.id
})
)
}
var shp_pois = Osmium.Output.Shapefile.open('./pois', 'point');
shp_pois.add_field('id', 'integer', 10);
shp_pois.add_field('type', 'string', 32);
shp_pois.add_field('name', 'string', 32);
var node_tags = {
amenity: { restaurant: 'restaurant', pub: 'pub' },
shop: { supermarket: 'supermarket' }
}
(continued...)
Osmium.Callbacks.node = function() {
for (var key in this.tags) {
if (node_tags[key]) {
var type = node_tags[key][this.tags[key]];
if (type) {
shp_pois.add(this.geom, {
id: this.id,
type: type,
name: this.tags.name
});
}
}
}
}
Osmium.Callbacks.end = function() {
shp_pois.close();
}
https://github.com/mikelmaron/Cartonama/blob/master/data/bangalore-bus-shp.zip
Creating Tiles w/ TileMill
@futura_med: "Kedage Normal", "Futura Medium","Function Pro Medium","Ubuntu Regular","Trebuchet MS Regular","DejaVu Sans Book","unifont Medium";
#bus_stops {
marker-width: 2;
marker-line-color: #00f;
text-fill: #b50d38;
text-name: "[name_kn]";
text-face-name: @futura_med;
text-size: 12;
text-dx: 5;
text-allow-overlap: false;
}
https://tiles.mapbox.com/groundtruth/map/map-busd5lm5
Ways to serve tiles ... TileCache (for imagery), TileStache, MapBox, mod_tile, etc
{
"cache": {
"name": "Disk",
"path": "/tmp/stache",
},
"layers": {
"blr": {
"provider": { "name": "mapnik", "mapfile": "style.xml" }
}
}
}
python tilestache-server.py -c tilestache.cfg
[cache]
type=Disk
base=/tmp/tilecache
[blr]
type=MapnikLayer
mapfile=style.xml
extension=png
srs=EPSG:3857
tms_type=google
python tilecache_http_server.py
https://tiles.mapbox.com/groundtruth/map/map-busd5lm5
survey Javascript Mapping APIs (OpenLayers, ModestMaps, GMaps API, Leaflet, Mapstraction)
leaflet and discussion
"Leaflet doesn't try to do everything for everyone. Instead it focuses on making the basic things work perfectly." * Most of what you might need (unless you need more)
http://leaflet.cloudmade.com/
ogr2ogr -f "GeoJSON" bangalore-stops.json bus_stops.shp
data/leaflet
show nominatim, geonames, overpass api
Create an app using, tiles and search, generated from the collected data.
https://github.com/yuvipanda/POSM http://yuvi.in/POSM/
| Table of Contents | t |
|---|---|
| Exposé | ESC |
| Full screen slides | e |
| Presenter View | p |
| Source Files | s |
| Slide Numbers | n |
| Toggle screen blanking | b |
| Show/hide slide context | c |
| Notes | 2 |
| Help | h |